package com.mebs.model;

import org.hibernate.Session;
import static org.hibernate.proxy.HibernateProxyHelper.getClassWithoutInitializingProxy;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Projections;

import javax.persistence.*;

import com.mebs.model.logistics.Transportation;
import com.mebs.model.logistics.Storage;
import com.mebs.model.inventory.PurchaseOrder;
import com.mebs.model.inventory.RelocationOrder;
import com.mebs.model.service.commercial.Commercial;
import com.mebs.model.service.visa.Visa;
import com.mebs.model.service.vehicle.Vehicle;
import com.mebs.model.service.accommodation.Accommodation;
import com.mebs.model.service.procurement.Procurement;

/**
 * Created by Sergey Prasolov, sap@jensentechnologies.com Date: Feb 13, 2006, 4:42:03 PM
 */
@Entity()
@Table(name = "PROJECT")
public class Project {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "Id")
    private Long id;

    @ManyToOne(optional = false)
    @JoinColumn(name = "CompanyId")
    private Company company;

    @Column(name = "Name", nullable = false, length = 250)
    private String name;

    @Column(name = "Description", nullable = true, length = 1024)
    private String description;

	@Column(name = "DetailedDescription", nullable = true, length = 1024)
    private String detailedDescription;

	@Embedded
    private AuditInfo auditInfo;

    /**
     * ********************** Getters-setters ***********************
     */
    public Long getId()
    {
        return id;
    }

    public void setId(Long id)
    {
        this.id = id;
    }

    public Company getCompany()
    {
        return company;
    }

    public void setCompany(Company company)
    {
        this.company = company;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getDescription()
    {
        return description;
    }

    public void setDescription(String description)
    {
        this.description = description;
    }

	public String getDetailedDescription() {
		return detailedDescription;
	}

	public void setDetailedDescription(String detailedDescription) {
		this.detailedDescription = detailedDescription;
	}

	public AuditInfo getAuditInfo()
    {
        if (this.auditInfo == null) {
            this.auditInfo = new AuditInfo();
        }
        return auditInfo;
    }

    public void setAuditInfo(AuditInfo auditInfo)
    {
        this.auditInfo = auditInfo;
    }

    @Override
    public String toString()
    {
        return this.name;
    }

    @Transient
    public boolean isDeletable(Session session)
    {
        // inventory
        if ((Integer) session.createCriteria(PurchaseOrder.class)
            .add(Restrictions.eq("project", this))
            .setProjection(Projections.rowCount())
            .uniqueResult() > 0) return false;
        if ((Integer)session.createCriteria(RelocationOrder.class)
            .add(Restrictions.eq("project", this))
            .setProjection(Projections.rowCount())
            .uniqueResult() > 0) return false;

        // logistics
        if ((Integer)session.createCriteria(Transportation.class)
            .add(Restrictions.eq("project", this))
            .setProjection(Projections.rowCount())
            .uniqueResult() > 0) return false;
        if ((Integer)session.createCriteria(Storage.class)
            .add(Restrictions.eq("project", this))
            .setProjection(Projections.rowCount())
            .uniqueResult() > 0) return false;

        // services
        if ((Integer)session.createCriteria(Commercial.class)
            .add(Restrictions.eq("project", this))
            .setProjection(Projections.rowCount())
            .uniqueResult() > 0) return false;
        if ((Integer)session.createCriteria(Visa.class)
            .add(Restrictions.eq("project", this))
            .setProjection(Projections.rowCount())
            .uniqueResult() > 0) return false;
        if ((Integer)session.createCriteria(Vehicle.class)
            .add(Restrictions.eq("project", this))
            .setProjection(Projections.rowCount())
            .uniqueResult() > 0) return false;
        if ((Integer)session.createCriteria(Accommodation.class)
            .add(Restrictions.eq("project", this))
            .setProjection(Projections.rowCount())
            .uniqueResult() > 0) return false;
        if ((Integer)session.createCriteria(Procurement.class)
            .add(Restrictions.eq("project", this))
            .setProjection(Projections.rowCount())
            .uniqueResult() > 0) return false;

        return true;
    }

    @Override
    public int hashCode()
    {
        if (id == null) return super.hashCode();
        return id.hashCode();
    }

    @Override
    public boolean equals(Object o)
    {
        if (o == null) return false;
        if (this == o) return true;
        if (id == null) return false;
        if (getClassWithoutInitializingProxy(this) != getClassWithoutInitializingProxy(o))
            return false;
        final Project that = (Project) o;
        return id.equals(that.getId());
    }

}
